package cn.zk.curator;

import com.google.common.base.Preconditions;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.utils.EnsurePath;
import org.apache.curator.utils.ZKPaths;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.common.PathUtils;
import org.apache.zookeeper.data.Stat;

import java.util.Objects;

/**
 * ClassName: ToolFirst
 * Desc: 工具类 ZKPaths、PathUtils、EnsurePath
 * Date： 2016/12/7
 * Created：shaom
 */
public class ToolFirst {

    static String tool_path = "/curator_tool_path";
    public static final String connectString = "master:2181,slave01:2181,slave02:2181";

    // 客户端
    CuratorFramework client = CuratorFrameworkFactory.builder().connectString(connectString)
            .sessionTimeoutMs(5000)
            .retryPolicy(new ExponentialBackoffRetry(5000, 3))
            .build();


    /**
     * /curator_tool_path/sub
     * /curator_tool_path/sub
     * sub1
     * /curator_tool_path
     * sub1
     * [child1, child2]
     *
     * @throws Exception
     */
    void testZKPaths() throws Exception {
        client.start();

        ZooKeeper zooKeeper = client.getZookeeperClient().getZooKeeper();

        System.out.println(ZKPaths.fixForNamespace(tool_path, "/sub"));

        System.out.println(ZKPaths.makePath(tool_path, "sub"));

        System.out.println(ZKPaths.makePath(tool_path, "a", "b", "c"));

        // "/one/two/three" will return "three"
        System.out.println(ZKPaths.getNodeFromPath(tool_path + "/sub1"));

        // "/one/two/three" will return {"/one/two", "three"}
        ZKPaths.PathAndNode pathAndNode = ZKPaths.getPathAndNode(tool_path + "/sub1");
        System.out.println(pathAndNode.getPath());
        System.out.println(pathAndNode.getNode());

        String dir1 = tool_path + "/child1";
        String dir2 = tool_path + "/child2";

        // 创建节点
        ZKPaths.mkdirs(zooKeeper, dir1);
        ZKPaths.mkdirs(zooKeeper, dir2);

        // Return the children
        System.out.println(ZKPaths.getSortedChildren(zooKeeper, tool_path));

        // 删除节点，并删除自己
        ZKPaths.deleteChildren(zooKeeper, tool_path, true);

    }

    /**
     * 校验Path
     */
    void testPathUtils() {
        PathUtils.validatePath(tool_path);
    }

    /**
     * 已经过时。
     * 被 CuratorFramework.create().creatingParentContainersIfNeeded() or CuratorFramework.exists().creatingParentContainersIfNeeded()
     * 操作某个节点进行操作，确保节点存在
     * 先需要判断，没有则需要创建。但是多线程环境并发的操作，B机器也在同时创建该节点，于是A机器创建的时候抛出“节点已经存在的异常”
     */
    void testEnsurePath() throws Exception {
        client.start();
        client.usingNamespace("zk_tool");

        EnsurePath ensurePath = new EnsurePath(tool_path);

        ensurePath.ensure(client.getZookeeperClient());
        ensurePath.ensure(client.getZookeeperClient());

        EnsurePath ensurePath1 = client.newNamespaceAwareEnsurePath("/c1");
        ensurePath1.ensure(client.getZookeeperClient());

    }


    void testDeprecated() throws Exception {
        client.start();

        Stat stat = client.checkExists().creatingParentContainersIfNeeded().forPath(tool_path + "1" + "/child");
        Preconditions.checkArgument(!Objects.isNull(stat), "节点不存在~");

        client.create().creatingParentContainersIfNeeded().forPath(tool_path + "1" + "/child");


    }


}
